package com.hzncc.flowable_diboot.job;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.diboot.core.holder.ThreadLocalHolder;
import com.diboot.core.util.BeanUtils;
import com.diboot.scheduler.annotation.CollectThisJob;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hzncc.flowable_diboot.entity.OaSync;
import com.hzncc.flowable_diboot.entity.system.OaDept;
import com.hzncc.flowable_diboot.entity.system.OaUser;
import com.hzncc.flowable_diboot.service.system.OaDeptService;
import com.hzncc.flowable_diboot.service.system.OaUserService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.util.ThreadContext;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.MultiValueMap;

import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

import org.springframework.http.MediaType;
import org.springframework.web.client.RestTemplate;

@DisallowConcurrentExecution
@CollectThisJob(
        name = "OA人员信息同步",
        cron = "0 0 1 * * ? *"
)
@Slf4j
public class OADataSyncJob extends QuartzJobBean implements ApplicationContextAware {

    @Value("${oa.syncOrg.url}")
    private String syncOrgUrl;

    @Value("${oa.syncOrg.authUsername}")
    private String oaAuthUsername;

    @Value("${oa.syncOrg.authPassword}")
    private String oaAuthPassword;

    @Resource
    private RestTemplate restTemplate;

    @Resource
    private SecurityManager securityManager;

    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Override
    public void executeInternal(JobExecutionContext context) throws JobExecutionException {

        OaUserService oaUserService = applicationContext.getBean(OaUserService.class);
        OaDeptService oaDeptService = applicationContext.getBean(OaDeptService.class);
        ThreadContext.bind(securityManager);

        String deptResponseBody = executeHttpRequest(syncOrgUrl, "{\r\n\t\"returnOrgType\": \"[{\\\"type\\\":\\\"dept\\\"}]\",\r\n\t\"count\": 10000\r\n}");
        List<OaDept> oaDeptList =  this.covertMessage(deptResponseBody, OaDept.class);
//        List<String> oaDeptIdList = oaDeptList.stream().map(OaDept::getId).collect(Collectors.toList());
//        boolean b = oaDeptService.deleteEntities(oaDeptIdList);
        oaDeptList.forEach(oaDept -> {
            if (StringUtils.isNotBlank(oaDept.getName())&& StringUtils.isNotBlank(oaDept.getNo())){
                oaDept.setName(oaDept.getName().replaceAll(oaDept.getNo(), ""));
            }
        });
        boolean dept = oaDeptService.createOrUpdateEntities(oaDeptList);
        log.info("OA部门信息同步完成，同步数量：{}", dept ? oaDeptList.size() : 0);

        String personResponseBody = executeHttpRequest(syncOrgUrl, "{\r\n\t\"returnOrgType\": \"[{\\\"type\\\":\\\"person\\\"}]\",\r\n\t\"count\": 10000\r\n}");
        List<OaUser> oaUserList =  this.covertMessage(personResponseBody, OaUser.class);
//        List<String> oaUserIdList = oaUserList.stream().map(OaUser::getId).collect(Collectors.toList());
//        oaUserService.deleteEntities(oaUserIdList);
        oaUserList.forEach(oaUser -> {
            if (StringUtils.isNotBlank(oaUser.getName())&& StringUtils.isNotBlank(oaUser.getNo())){
                oaUser.setName(oaUser.getName().replaceAll(oaUser.getNo(), ""));
            }
        });
        boolean user = oaUserService.createOrUpdateEntities(oaUserList);
        log.info("OA人员信息同步完成，同步数量：{}", user ? oaUserList.size() : 0);



    }

    private String executeHttpRequest(String url, String body) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.setAccept(List.of(MediaType.APPLICATION_JSON));
        headers.setBasicAuth(oaAuthUsername, oaAuthPassword);

        HttpEntity<String> requestEntity = new HttpEntity<>(body, headers);
        ResponseEntity<String> response = restTemplate.postForEntity(url, requestEntity, String.class);
        if (response.getStatusCode().is2xxSuccessful()) {
            return response.getBody();
        } else {
            throw new RuntimeException("HTTP request failed with status code: " + response.getStatusCodeValue());
        }

    }

    private List covertMessage(String message,Class<?> clazz) {
        ObjectMapper objectMapper = new ObjectMapper();
        List result = null;
        try {
            JsonNode jsonNode = objectMapper.readTree(message);
            if (jsonNode.has("message")) {
                String messageString = jsonNode.get("message").asText();
                JsonNode messageArrayNode = objectMapper.readTree(messageString);
                List<OaSync> oaDataList = objectMapper.convertValue(messageArrayNode, new TypeReference<>() {});
                result = BeanUtils.convertList(oaDataList, clazz);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return result;
    }
}
